/**
 * // Copyright (c) 2023 KylinOS. All rights reserved.
 * //
 * // This program is free software; you can redistribute it
 * // and/or modify it under the terms of the GNU General Public
 * // License (version 2) as published by the FSF - Free Software
 * // Foundation*
 */

/**
 * // Copyright (C) 2023 ben LG <guoliben@kylinos.cn>
 */

package docextractor

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"time"

	"gitee.com/guoliben/kydlp-doctotext/extractor_interface"
	"gitee.com/guoliben/kydlp-doctotext/utils/ctrlledprint"
)

type DocJson struct{}

// 解析 json 文档内容
func (extractor DocJson) GetTextFromFile(path string, size int64, filetype string, depth int) ([]byte, string) {
	ctrlledprint.Println("提取文本: 正在解析json(file)文档...")

	return DocText{}.GetTextFromFile(path, size, filetype, depth)

	start := time.Now()

	content, err := ioutil.ReadFile(path)
	if err != nil {
		ctrlledprint.Println("Error reading json file:", err)
		return nil, ""
	}

	var jsonData interface{}
	err = json.Unmarshal(content, &jsonData)
	if err != nil {
		ctrlledprint.Println("Error decoding json file:", err)
		return nil, ""
	}

	text := extractTextFromJSON(jsonData)

	elapsed := time.Since(start)

	return text, elapsed.String()
}

func (extractor DocJson) GetTextFromBuffer(path string, data []byte, size int64, filetype string, depth int) ([]byte, string) {
	ctrlledprint.Println("提取文本: 正在解析json(buffer)文档...")

	return DocText{}.GetTextFromBuffer(path, data, size, filetype, depth)

	start := time.Now()

	var jsonData interface{}
	err := json.Unmarshal(data, &jsonData)
	if err != nil {
		ctrlledprint.Println("Error decoding json file:", err)
		return nil, ""
	}

	text := extractTextFromJSON(jsonData)

	elapsed := time.Since(start)

	return text, elapsed.String()
}

func (extractor DocJson) GetStringTextFromFile(path string, size int64, filetype string, depth int) (string, string) {
	ctrlledprint.Println("提取文本: 正在解析json(file)文档...")

	return DocText{}.GetStringTextFromFile(path, size, filetype, depth)

	start := time.Now()

	content, err := ioutil.ReadFile(path)
	if err != nil {
		ctrlledprint.Println("Error reading json file:", err)
		return "", ""
	}

	var jsonData interface{}
	err = json.Unmarshal(content, &jsonData)
	if err != nil {
		ctrlledprint.Println("Error decoding json file:", err)
		return "", ""
	}

	text := extractStringTextFromJSON(jsonData)

	elapsed := time.Since(start)

	return text, elapsed.String()
}

func (extractor DocJson) GetStringTextFromBuffer(path string, data []byte, size int64, filetype string, depth int) (string, string) {
	ctrlledprint.Println("提取文本: 正在解析json(buffer)文档...")

	return DocText{}.GetStringTextFromBuffer(path, data, size, filetype, depth)

	start := time.Now()

	var jsonData interface{}
	err := json.Unmarshal(data, &jsonData)
	if err != nil {
		ctrlledprint.Println("Error decoding json file:", err)
		return "", ""
	}

	text := extractStringTextFromJSON(jsonData)

	elapsed := time.Since(start)

	return text, elapsed.String()
}

func extractTextFromJSON(data interface{}) []byte {
	var text bytes.Buffer

	switch value := data.(type) {
	case string:
		text.WriteString(value)
		text.WriteString(" ")
	case []interface{}:
		for _, item := range value {
			text.Write(extractTextFromJSON(item))
		}
	case map[string]interface{}:
		for _, v := range value {
			text.Write(extractTextFromJSON(v))
		}
	}

	return text.Bytes()
}

func extractStringTextFromJSON(data interface{}) string {
	var text bytes.Buffer

	switch value := data.(type) {
	case string:
		text.WriteString(value)
		text.WriteString(" ")
	case []interface{}:
		for _, item := range value {
			text.WriteString(extractStringTextFromJSON(item))
		}
	case map[string]interface{}:
		for _, v := range value {
			text.WriteString(extractStringTextFromJSON(v))
		}
	}

	return text.String()
}

//func (extractor DocJson) GetTextFromFileWithCallback(path string, size int64, filetype string, depth int, callback extractor_interface.OnTextDetectHandler, context interface{}) (int, string, string) {
//	var retcode int
//
//	text, elapsed := extractor.GetTextFromFile(path, size, filetype, depth)
//
//	if callback != nil {
//		retcode, _ = callback(path, size, filetype, text, len(text), context)
//	}
//
//	return retcode, text, elapsed
//}
//
//func (extractor DocJson) GetTextFromBufferWithCallback(path string, data []byte, size int64, filetype string, depth int, callback extractor_interface.OnTextDetectHandler, context interface{}) (int, string, string) {
//	var retcode int
//
//	text, elapsed := extractor.GetTextFromBuffer(path, data, size, filetype, depth)
//
//	if callback != nil {
//		retcode, _ = callback(path, size, filetype, text, len(text), context)
//	}
//
//	return retcode, text, elapsed
//}

func (extractor DocJson) GetTextFromFileWithCallback(path string, size int64, filetype string, depth int, callback extractor_interface.OnTextDetectHandler, context interface{}) (int, []byte, string) {
	return DocText{}.GetTextFromFileWithCallback(path, size, filetype, depth, callback, context)
}

func (extractor DocJson) GetTextFromBufferWithCallback(path string, data []byte, size int64, filetype string, depth int, callback extractor_interface.OnTextDetectHandler, context interface{}) (int, []byte, string) {
	return DocText{}.GetTextFromBufferWithCallback(path, data, size, filetype, depth, callback, context)
}

func (extractor DocJson) GetStringTextFromFileWithCallback(path string, size int64, filetype string, depth int, callback extractor_interface.OnStringTextDetectHandler, context interface{}) (int, string, string) {
	return DocText{}.GetStringTextFromFileWithCallback(path, size, filetype, depth, callback, context)
}

func (extractor DocJson) GetStringTextFromBufferWithCallback(path string, data []byte, size int64, filetype string, depth int, callback extractor_interface.OnStringTextDetectHandler, context interface{}) (int, string, string) {
	return DocText{}.GetStringTextFromBufferWithCallback(path, data, size, filetype, depth, callback, context)
}
